import './index.css';
import resizer from './resizer';
import { computed, defineComponent, type PropType, ref, unref } from 'vue';

export interface ContextProps {
	minPercent: number;
	defaultPercent: number;
	split: string;
}

/** 切割面板组件 */
export default defineComponent({
	name: 'SplitPane',
	components: { resizer },
	props: {
		splitSet: {
			type: Object as PropType<ContextProps>,
			require: true,
		},
	},
	emits: ['resize'],
	setup(props, ctx) {
		const active = ref(false);
		const hasMoved = ref(false);
		const percent = ref(props.splitSet?.defaultPercent);
		const type = props.splitSet?.split === 'vertical' ? 'width' : 'height';
		const resizeType = props.splitSet?.split === 'vertical' ? 'left' : 'top';

		const leftClass = ref(['splitter-pane splitter-paneL', props.splitSet?.split]);

		const rightClass = ref(['splitter-pane splitter-paneR', props.splitSet?.split]);

		const cursor = computed(() => {
			return active.value ? (props.splitSet?.split === 'vertical' ? { cursor: 'col-resize' } : { cursor: 'row-resize' }) : { cursor: 'default' };
		});

		const onClick = (): void => {
			if (!hasMoved.value) {
				percent.value = 50;
				ctx.emit('resize', percent.value);
			}
		};

		const onMouseDown = (): void => {
			active.value = true;
			hasMoved.value = false;
		};

		const onMouseUp = (): void => {
			active.value = false;
		};

		const onMouseMove = (e: any): void => {
			if (e.buttons === 0 || e.which === 0) {
				active.value = false;
			}

			if (active.value) {
				let offset = 0;
				let target = e.currentTarget;
				if (props.splitSet?.split === 'vertical') {
					while (target) {
						offset += target.offsetLeft;
						target = target.offsetParent;
					}
				} else {
					while (target) {
						offset += target.offsetTop;
						target = target.offsetParent;
					}
				}

				const currentPage = props.splitSet?.split === 'vertical' ? e.pageX : e.pageY;
				const targetOffset = props.splitSet?.split === 'vertical' ? e.currentTarget.offsetWidth : e.currentTarget.offsetHeight;
				const percents = Math.floor(((currentPage - offset) / targetOffset) * 10000) / 100;

				if (percents > props.splitSet?.minPercent && percents < 100 - props.splitSet?.minPercent) {
					percent.value = percents;
				}

				ctx.emit('resize', percent.value);

				hasMoved.value = true;
			}
		};

		return () => (
			<>
				<div class='vue-splitter-container clearfix' style={unref(cursor)} onMouseup={() => onMouseUp()} onMousemove={() => onMouseMove(event)}>
					<div class={unref(leftClass)} style={{ [unref(type)]: unref(percent) + '%' }}>
						{ctx.slots.paneL()}
					</div>
					<resizer style={`${unref([resizeType])}:${unref(percent)}%`} split={props.splitSet?.split} onMousedown={() => onMouseDown()} onClick={() => onClick()}></resizer>
					<div class={unref(rightClass)} style={{ [unref(type)]: 100 - unref(percent) + '%' }}>
						{ctx.slots.paneR()}
					</div>
					<div v-show={unref(active)} class='vue-splitter-container-mask'></div>
				</div>
			</>
		);
	},
});
